<template>
  <el-table
    border
    :lazy="true"
    @mousedown.native="down($event)"
    @mousemove.native="move($event)"
    @mouseup.native="up($event)"
    :data="historyDataTables"
    :highlight-current-row="true"
    :stripe="true"
    :row-height="30"
    :cell-style="cellStyle"
    ref="multipleTable"
    height="500px"
  >
    <slot />
  </el-table>
</template>
<!--          -->

<script>
export default {
  props: {
    historyDataTables: {
      type: Array,
      default: () => [],
    },
  },
  data() {
    return {
      // 列表集合
      // historyDataTables: [
      //   {
      //     id: 1,
      //     name: "zs",
      //     age: 18,
      //     sex: "男",
      //   },
      //   {
      //     id: 2,
      //     name: "ls",
      //     age: 28,
      //     sex: "男",
      //   },
      //   {
      //     id: 3,
      //     name: "ww",
      //     age: 38,
      //     sex: "女",
      //   },
      //   {
      //     id: 4,
      //     name: "ww",
      //     age: 38,
      //     sex: "女",
      //   },
      //   {
      //     id: 5,
      //     name: "ww",
      //     age: 38,
      //     sex: "女",
      //   },
      //   {
      //     id: 6,
      //     name: "ww",
      //     age: 38,
      //     sex: "女",
      //   },
      // ],

      xqArr: [],
      select: false,
      isMouseDown: true, // 是否需要(允许)处理鼠标的移动事件
      // 定义移动元素div
      rect: null,
      // 记录鼠标按下时的坐标
      downX: 0,
      downY: 0,
      // 记录鼠标抬起时候的坐标
      mouseX2: this.downX,
      mouseY2: this.downY,
      // 表格dom元素
      TableDom: null,
      tableHeaderHeight: 0,
      selectedData: [], // 鼠标框选选中的数据
      selectedCellTop: 0, // 选中单元格距离el-table顶部的距离
      selectedCellLeft: 0, // 选中单元格距离el-table左侧的距离

      tableRectTop: 0, // el-table距离window顶部的距离
      tableRectLeft: 0, // el-table距离window左侧的距离
      tableScrollTop: 0, // el-table滚动的距离
    };
  },
  mounted() {
    this.init();
  },

  beforeDestroy() {
    window.removeEventListener("resize", this.getTableMarginLeft);
  },
  methods: {
    /* 表格合并列和行 */
    objectSpanMethod({ row, column, rowIndex, columnIndex }) {
      if (columnIndex === 0) {
        const _row = this.flitterData(this.historyDataTables).one[rowIndex];
        const _col = _row > 0 ? 1 : 0;
        return {
          rowspan: _row,
          colspan: _col,
        };
      }
    } /**合并表格的第一列，处理表格数据 */,
    flitterData(arr) {
      let spanOneArr = [];
      let concatOne = 0;
      arr.forEach((item, index) => {
        if (index === 0) {
          spanOneArr.push(1);
        } else {
          //注意这里的quarterly是表格绑定的字段，根据自己的需求来改
          if (item.机组名称 === arr[index - 1].机组名称) {
            //第一列需合并相同内容的判断条件
            spanOneArr[concatOne] += 1;
            spanOneArr.push(0);
          } else {
            spanOneArr.push(1);
            concatOne = index;
          }
        }
      });
      return {
        one: spanOneArr,
      };
    },
    // 页面初始化
    init() {
      this.TableDom = this.$refs.multipleTable.$el; // 获取table元素
      // 获取table的位置,监听窗口变化,table的距离变化
      this.getTableMarginLeft();
      window.addEventListener("resize", this.getTableMarginLeft);

      this.clientWidth =
        document.documentElement.clientWidth || document.body.clientWidth;
      this.clientHeight =
        document.documentElement.clientHeight || document.body.cientHeight;

      this.otherHeight =
        Math.ceil($(".is-always-shadow").outerHeight()) +
        Math.ceil($(".is-top").outerHeight());

      this.maxHeight1 = this.clientHeight - this.otherHeight - 150 + "px";

      var that = this;
      window.onresize = () => {
        return (() => {
          window.clientHeight =
            document.documentElement.clientHeight || document.body.clientHeight;
          that.clientHeight = window.clientHeight;
        })();
      };
    },

    cellStyle({ row, column, rowIndex, columnIndex }) {
      // 对xqArr选择选区的单元格加蓝边框
      // console.log("this.xqArr", this.xqArr);
      let matchObj = this.xqArr.find(
        (item) => item.columnIndex === columnIndex && item.rowIndex === rowIndex
      );
      // console.log("matchObj", matchObj);
      if (matchObj) {
        // 选中
        if (row.checkArr) {
          row.checkArr.push(column.property);
        } else {
          row.checkArr = [column.property];
        }
        // 效验，不能跨机组填
        if (!this.vilide()) {
          this.historyDataTables.forEach((item) => {
            if (item.checkArr) item.checkArr = [];
          });
          this.xqArr = [];
          this.$message.info("不能跨机组框选，不可只框选日分析行");
        }
        this.$emit("selectChange");
        return { border: "1px solid #5E99FD" };
      }
    },
    vilide() {
      const list = this.historyDataTables.reduce((prev, item) => {
        if (item?.checkArr && item?.checkArr?.length && item.时间 != '日分析' ) {
          const obj = prev.find((i) => i == item.机组名称 );
          if (!obj) prev.push(item.机组名称);
        }

        return prev;
      }, []);
      console.log("vilide", list);
      if (list.length == 1) {
        // if (list[0]?.checkArr?.length == 0) {
        //   return false;
        // } else {
        //   return true;
        // }
        return true
      } else {
        return false;
      }
    },

    // 获取table距离页面左侧和上方的距离
    getTableMarginLeft() {
      const tableRect = this.TableDom.getBoundingClientRect(); // 获取el-table元素的位置信息
      this.tableRectTop = Math.ceil(tableRect.top);
      this.tableRectLeft = Math.ceil(tableRect.left);
    },

    down(event) {
      // 当允许鼠标按下时,才允许处理鼠标的移动事件,这里结合项目其他问题所以设置了判断条件
      if (this.isMouseDown) {
        console.log("清空了");
        this.xqArr = []; // 清空上一次选择
        this.historyDataTables.forEach((item) => {
          if (item.checkArr) item.checkArr = [];
        });
        this.$emit("selectChange");

        // this.selectedData = [];
        this.select = true;
        this.rect = document.createElement("div");
        // 框选div 样式
        this.rect.style.cssText =
          "position:absolute;width:0px;height:0px;font-size:0px;margin:0px;padding:0px;border:1px solid #0099FF;background-color:#C3D5ED;z-index:1000;filter:alpha(opacity:60);opacity:0.6;display:none;";
        this.rect.id = "selectDiv";
        this.getTableMarginLeft();

        const container = document.querySelector(".el-table__body-wrapper"); // 获取table容器元素
        this.TableDom.appendChild(this.rect); // 添加到table元素下

        // 取得鼠标按下时的坐标位置
        this.downX =
          event.x || event.clientX + container.scrollLeft - this.tableRectLeft; // 鼠标按下时的x轴坐标 event.x 兼容火狐浏览器, event.clientX 兼容谷歌浏览器
        this.downY =
          event.y || event.clientY + container.scrollTop - this.tableRectTop; // 鼠标按下时的y轴坐标

        this.rect.style.left = this.downX + "px"; // 设置你要画的矩形框的起点位置
        this.rect.style.top = this.downY + "px"; // 设置你要画的矩形框的起点位置
        //设置你要画的矩形框的起点位置
        this.rect.style.left = this.downX; // 因为在火狐浏览器下,上面的代码不起作用,所以在这里再写一遍，为什么火狐浏览器不起作用,因为火狐浏览器下,我们的div是绝对定位的,所以我们要加上px，为什么这里没加px,因为我们下面要加上px,所以这里不用加
        this.rect.style.top = this.downY;
      } else {
        return;
      }
    },
    move(event) {
      /*
      这个部分,根据你鼠标按下的位置,和你拉框时鼠标松开的位置关系,可以把区域分为四个部分,根据四个部分的不同,
      我们可以分别来画框,否则的话,就只能向一个方向画框,也就是点的右下方画框.
      */
      if (this.select && this.isMouseDown) {
        // 取得鼠标移动时的坐标位置
        this.mouseX2 = event.clientX; // 鼠标移动时的x轴坐标
        this.mouseY2 = event.clientY; // 鼠标移动时的y轴坐标
        // 框选元素的显示与隐藏
        if (this.rect.style.display == "none") {
          this.rect.style.display = "";
        }
        // 框选元素的位置处理
        this.rect.style.left =
          Math.min(this.mouseX2, this.downX) - this.tableRectLeft + "px";

        this.rect.style.top =
          Math.min(this.mouseY2, this.downY) - this.tableRectTop + "px"; // 取得鼠标拉框时的起点坐标

        this.rect.style.width = Math.abs(this.mouseX2 - this.downX) + "px"; // 取得鼠标拉框时的宽度

        this.rect.style.height = Math.abs(this.mouseY2 - this.downY) + "px"; // 取得鼠标拉框时的高度
        // A part
        if (this.mouseX2 < this.downX && this.mouseY2 < this.downY) {
          this.rect.style.left = this.mouseX2 + this.tableRectLeft;
          this.rect.style.top = this.mouseY2 + this.tableRectTop;
        }

        // B part
        if (this.mouseX2 > this.downX && this.mouseY2 < this.downY) {
          this.rect.style.left = this.downX + this.tableRectLeft;
          this.rect.style.top = this.mouseY2 + this.tableRectTop;
        }

        // C part
        if (this.mouseX2 < this.downX && this.mouseY2 > this.downY) {
          this.rect.style.left = this.mouseX2 + this.tableRectLeft;
          this.rect.style.top = this.downY + this.tableRectTop;
        }

        // D part
        if (this.mouseX2 > this.downX && this.mouseY2 > this.downY) {
          this.rect.style.left = this.downX + this.tableRectLeft;
          this.rect.style.top = this.downY + this.tableRectTop;
        }
      } else {
        return;
      }

      this.stopEvent(event);
    },
    // 阻止默认事件
    stopEvent(event) {
      if (event.stopPropagation) {
        // 标准浏览器
        event.stopPropagation(); // 阻止事件冒泡
        event.preventDefault(); // 阻止默认事件
      } else {
        // IE浏览器
        event.cancelBubble = true;
        event.returnValue = false;
      }
    },
    // 鼠标抬起事件
    up() {
      if (!this.select || !this.isMouseDown) return;

      const container = document.querySelector(".el-table__body-wrapper"); // 获取table容器元素
      const scrollTop = container.scrollTop; // 获取el-table的scrollTop和scrollLeft
      const scrollLeft = container.scrollLeft;

      const headerWrapper = this.TableDom.querySelector(
        ".el-table__header-wrapper"
      );
      const tableHeaderHeight = Math.ceil(
        headerWrapper.getBoundingClientRect().height
      );

      // const columns = this.$refs.multipleTable.columns; // 表格的标题

      const rectLeft = this.rect.offsetLeft + scrollLeft - this.tableRectLeft;
      const rectTop =
        this.rect.offsetTop + scrollTop - this.tableRectTop - tableHeaderHeight;

      const tableBody = document.querySelector(".el-table__body");

      tableBody.children[1].childNodes.forEach((element) => {
        for (let index = 0; index < element.childNodes.length; index++) {
          // 获取当前单元格
          const cell = element.childNodes[index];
          if (
            // 判断选中的单元格是否在鼠标拉框的范围内
            rectLeft <
              cell.offsetLeft - this.tableRectLeft + cell.offsetWidth &&
            rectLeft + this.rect.offsetWidth >
              cell.offsetLeft - this.tableRectLeft &&
            rectTop < cell.offsetTop - this.tableRectTop + cell.offsetHeight &&
            rectTop + this.rect.offsetHeight >
              cell.offsetTop - this.tableRectTop &&
            index >= 3 // 选中的单元格所在列的索引大于等于3
          ) {
            if (cell.className.indexOf("add") == -1) {
              const rowIndex = element.rowIndex; // 将当前单元格所在的行数据加入到该列数据中
              const columnIndex = index;

              // 选择要添加到选中行数组中的属性
              const selected = {
                // rowId: rowData.id,
                rowIndex: rowIndex,
                columnIndex: columnIndex,
              };
              // console.log("selected", selected);
              this.xqArr.push(selected);
            }
          }
        }
      });

      //鼠标抬起,就不允许在处理鼠标移动事件
      this.select = false;

      //隐藏图层
      if (this.rect) {
        this.TableDom.removeChild(this.rect);
      }
    },
  },
};
</script>
<style lang="scss" scoped>
::v-deep .el-table td.blue-cell {
  border: 1px solid blue !important;
}
</style>
